/*
 * Copyright 2011-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0.
 * See `LICENSE` in the project root for license information.
 */

package me.ijleex.mgmt.system.auth.service.impl;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RestController;

import me.ijleex.mgmt.commons.util.snowflake.IdWorker;
import me.ijleex.mgmt.framework.entity.Result;
import me.ijleex.mgmt.system.auth.model.JwtUser;
import me.ijleex.mgmt.system.auth.service.IAuthService;
import me.ijleex.mgmt.system.auth.service.IJwtService;
import me.ijleex.mgmt.system.role.mapper.RoleMapper;
import me.ijleex.mgmt.system.user.entity.User;
import me.ijleex.mgmt.system.user.entity.UserRole;
import me.ijleex.mgmt.system.user.mapper.UserMapper;
import me.ijleex.mgmt.system.user.mapper.UserRoleMapper;

/**
 * AuthServiceImpl.
 *
 * @author liym
 * @since 2020-08-09 14:39 新建
 */
@RestController
public class AuthServiceImpl implements IAuthService {

    private static final String DEFAULT_ROLE_NAME = "ROLE_USER";

    private final AuthenticationManager authenticationManager;
    private final JwtUserServiceImpl jwtUserService;
    private final IJwtService jwtService;

    private final UserMapper userMapper;
    private final RoleMapper roleMapper;
    private final UserRoleMapper userRoleMapper;

    private final PasswordEncoder passwordEncoder;

    public AuthServiceImpl(AuthenticationManager authenticationManager, JwtUserServiceImpl jwtUserService, IJwtService jwtService,
            UserMapper userMapper, RoleMapper roleMapper, UserRoleMapper userRoleMapper,
            PasswordEncoder passwordEncoder) {
        this.authenticationManager = authenticationManager;
        this.jwtUserService = jwtUserService;
        this.jwtService = jwtService;
        this.userMapper = userMapper;
        this.roleMapper = roleMapper;
        this.userRoleMapper = userRoleMapper;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Result login(String login, String password) {
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(login, password);
        try {
            Authentication authentication = this.authenticationManager.authenticate(authToken);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (BadCredentialsException e) {
            return Result.error("用户名或密码不正确");
        }
        JwtUser jwtUser = (JwtUser) this.jwtUserService.loadUserByUsername(login);
        return this.jwtService.createToken(jwtUser.getUserId(), login, jwtUser.getPassword(), jwtUser.getAuthorities());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result register(String login, String password, String captchaCode) {
        if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
            return Result.error("用户名或密码不能为空");
        }
        Boolean usernameExists = this.userMapper.isUsernameExists(login);
        if (usernameExists != null && usernameExists) {
            return Result.error("用户名已存在");
        }
        User user = new User();
        user.setId(IdWorker.getId());
        user.setUsername(login);
        user.setName("用户" + login);
        String encodedPwd = this.passwordEncoder.encode(password);
        user.setPassword(encodedPwd);
        user.setState(0);
        user.setCreator(login);
        int x = this.userMapper.insert(user);
        if (x == 0) {
            return Result.error("用户注册失败");
        } else {
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getId());
            userRole.setRoleId(this.roleMapper.selectIdByName(DEFAULT_ROLE_NAME));
            userRole.setCreator(user.getUsername());
            this.userRoleMapper.insert(userRole);
            return Result.ok("用户注册成功");
        }
    }

}
